package domain

import (
	"context"
	"fmt"
	"mime/multipart"
	"net/http"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/mars/internal/pkg/wxcloud"
	"github.com/mars/pkg/errors"
)

// ProductType 商品类型枚举
type ProductType string

const (
	ProductTypeVIP      ProductType = "vip"      // VIP会员
	ProductTypeTicket   ProductType = "ticket"   // 入场券
	ProductTypePhysical ProductType = "physical" // 实物商品
)

// ProductStatus 商品状态枚举
type ProductStatus string

const (
	ProductStatusActive   ProductStatus = "active"   // 上架
	ProductStatusInactive ProductStatus = "inactive" // 下架
)

// VipDiscountInfo VIP折扣信息
type VipDiscountInfo struct {
	Type  string `json:"type" bson:"type"`   // 折扣类型: percent|amount
	Value int    `json:"value" bson:"value"` // 折扣值（百分比或金额分）
}

// Specification 商品规格
type Specification struct {
	Name            string `json:"name" bson:"name"`                       // 规格名称 3.6米红色鱼竿 4米红色鱼竿
	Stock           int    `json:"stock" bson:"stock"`                     // 该规格库存
	PriceAdjustment int    `json:"priceAdjustment" bson:"priceAdjustment"` // 价格调整（分）
}

// Product 商品实体
type Product struct {
	ID             string           `json:"_id,omitempty" bson:"_id,omitempty"`                       // 商品ID
	Name           string           `json:"name" bson:"name"`                                         // 商品名称
	Description    string           `json:"description" bson:"description"`                           // 商品描述
	Detail         string           `json:"detail" bson:"detail"`                                     // 商品详情
	Price          int              `json:"price" bson:"price"`                                       // 商品价格（分）
	Image          string           `json:"image" bson:"image"`                                       // 主图片
	Images         []string         `json:"images" bson:"images"`                                     // 图片列表
	Type           ProductType      `json:"type" bson:"type"`                                         // 商品类型
	Status         ProductStatus    `json:"status" bson:"status"`                                     // 商品状态
	Sort           int              `json:"sort" bson:"sort"`                                         // 排序
	Stock          *int             `json:"stock,omitempty" bson:"stock,omitempty"`                   // 库存（仅实物商品）
	TicketType     TicketType       `json:"ticketType,omitempty" bson:"ticketType,omitempty"`         // 票券类型（仅入场券）
	VipDiscount    *VipDiscountInfo `json:"vipDiscount,omitempty" bson:"vipDiscount,omitempty"`       // VIP折扣（仅入场券）
	Specifications []Specification  `json:"specifications,omitempty" bson:"specifications,omitempty"` // 商品规格（仅实物商品）
	CreatedBy      string           `json:"createdBy" bson:"createdBy"`                               // 创建者
	CreateTime     int64            `json:"createTime" bson:"createTime"`                             // 创建时间（秒级时间戳）
	UpdateTime     int64            `json:"updateTime" bson:"updateTime"`                             // 更新时间（秒级时间戳）
}

// ProductQueryParams 商品查询参数
type ProductQueryParams struct {
	Type    ProductType   `json:"type,omitempty"`    // 商品类型过滤
	Status  ProductStatus `json:"status,omitempty"`  // 状态过滤
	Keyword string        `json:"keyword,omitempty"` // 关键字搜索
	PaginationParams
	SortParams
}

// NewDefaultProductQueryParams 创建默认商品查询参数
func NewDefaultProductQueryParams() ProductQueryParams {
	return ProductQueryParams{
		PaginationParams: DefaultPaginationParams,
		SortParams:       DefaultSortParams,
	}
}

// ProductValidator 商品验证器
type ProductValidator struct {
	paginationValidator  *PaginationValidator
	idValidator          *IDValidator
	sortValidator        *SortValidator
	typeValidator        *EnumValidator
	statusValidator      *EnumValidator
	nameValidator        *StringValidator
	descriptionValidator *StringValidator
	keywordValidator     *StringValidator
}

// NewProductValidator 创建商品验证器
func NewProductValidator() *ProductValidator {
	return &ProductValidator{
		paginationValidator: NewPaginationValidator(100),
		idValidator:         NewIDValidator("product ID", 1, 128),
		sortValidator:       NewSortValidator([]string{"createTime", "updateTime", "sort", "price", "name"}),
		typeValidator: NewEnumValidator("product type",
			[]string{string(ProductTypeVIP), string(ProductTypeTicket), string(ProductTypePhysical)}, false),
		statusValidator: NewEnumValidator("product status",
			[]string{string(ProductStatusActive), string(ProductStatusInactive)}, false),
		nameValidator:        NewStringValidator("product name", 100, false),
		descriptionValidator: NewStringValidator("product description", 1000, false),
		keywordValidator:     NewStringValidator("search keyword", 100, false),
	}
}

// ValidateQueryParams 验证查询参数
func (pv *ProductValidator) ValidateQueryParams(cxt *gin.Context) (ProductQueryParams, error) {
	// 验证分页参数
	pagination, err := pv.paginationValidator.ValidateAndParse(cxt)
	if err != nil {
		return ProductQueryParams{}, err
	}

	// 验证排序参数
	sort, err := pv.sortValidator.ValidateAndParse(cxt)
	if err != nil {
		return ProductQueryParams{}, err
	}

	// 验证商品类型
	productType := cxt.Query("type")
	if err := pv.typeValidator.Validate(productType); err != nil {
		return ProductQueryParams{}, err
	}

	// 验证商品状态
	status := cxt.Query("status")
	if err := pv.statusValidator.Validate(status); err != nil {
		return ProductQueryParams{}, err
	}

	// 验证关键字
	keyword := cxt.Query("keyword")
	if err := pv.keywordValidator.Validate(keyword); err != nil {
		return ProductQueryParams{}, err
	}

	return ProductQueryParams{
		Type:             ProductType(productType),
		Status:           ProductStatus(status),
		Keyword:          keyword,
		PaginationParams: pagination,
		SortParams:       sort,
	}, nil
}

// ValidateProductID 验证商品ID
func (pv *ProductValidator) ValidateProductID(cxt *gin.Context, paramName string) (string, error) {
	return pv.idValidator.ValidateFromParam(cxt, paramName)
}

// ValidateProductType 验证商品类型参数
func (pv *ProductValidator) ValidateProductType(cxt *gin.Context, paramName string) (ProductType, error) {
	typeStr := cxt.Param(paramName)
	if typeStr == "" {
		typeStr = cxt.Query(paramName)
	}

	typeValidator := NewEnumValidator("product type",
		[]string{string(ProductTypeVIP), string(ProductTypeTicket), string(ProductTypePhysical)}, true)
	if err := typeValidator.Validate(typeStr); err != nil {
		return "", err
	}

	return ProductType(typeStr), nil
}

// ValidateProductStatus 验证商品状态参数
func (pv *ProductValidator) ValidateProductStatus(cxt *gin.Context, paramName string) (ProductStatus, error) {
	statusStr := cxt.Param(paramName)
	if statusStr == "" {
		statusStr = cxt.Query(paramName)
	}

	statusValidator := NewEnumValidator("product status",
		[]string{string(ProductStatusActive), string(ProductStatusInactive)}, true)
	if err := statusValidator.Validate(statusStr); err != nil {
		return "", err
	}

	return ProductStatus(statusStr), nil
}

// ValidateProduct 验证商品实体
func (pv *ProductValidator) ValidateProduct(product *Product) error {
	if product == nil {
		return errors.New(http.StatusBadRequest, "product object is required")
	}

	// 验证商品名称
	nameValidator := NewStringValidator("product name", 100, true)
	if err := nameValidator.Validate(product.Name); err != nil {
		return err
	}

	// 验证商品价格
	if product.Price <= 0 {
		return errors.New(http.StatusBadRequest, "product price must be greater than 0")
	}

	// 验证商品类型
	if product.Type == "" {
		return errors.New(http.StatusBadRequest, "product type is required")
	}

	if err := pv.typeValidator.Validate(string(product.Type)); err != nil {
		return err
	}

	// 验证商品描述
	if err := pv.descriptionValidator.Validate(product.Description); err != nil {
		return err
	}

	// 验证实物商品的库存
	if product.Type == ProductTypePhysical && product.Stock != nil && *product.Stock < 0 {
		return errors.New(http.StatusBadRequest, "product stock cannot be negative")
	}

	return nil
}

// ValidateSearchKeyword 验证搜索关键字
func (pv *ProductValidator) ValidateSearchKeyword(cxt *gin.Context) (string, error) {
	keyword := cxt.Query("keyword")
	keywordValidator := NewStringValidator("search keyword", 100, true)
	if err := keywordValidator.Validate(keyword); err != nil {
		return "", err
	}
	return keyword, nil
}

// ValidateUpdateStatusRequest 验证更新状态请求
func (pv *ProductValidator) ValidateUpdateStatusRequest(status ProductStatus) error {
	return pv.statusValidator.Validate(string(status))
}

// ValidateUpdateStockRequest 验证更新库存请求
func (pv *ProductValidator) ValidateUpdateStockRequest(stock int) error {
	if stock < 0 {
		return errors.New(http.StatusBadRequest, "stock cannot be negative")
	}
	return nil
}

// ProductStats 商品统计信息
type ProductStats struct {
	Total         int64 `json:"total"`         // 总商品数
	VipCount      int64 `json:"vipCount"`      // VIP商品数
	TicketCount   int64 `json:"ticketCount"`   // 入场券商品数
	PhysicalCount int64 `json:"physicalCount"` // 实物商品数
	ActiveCount   int64 `json:"activeCount"`   // 上架商品数
	InactiveCount int64 `json:"inactiveCount"` // 下架商品数
}

// ProductGateway 商品网关接口
type ProductGateway interface {
	// GetProductList 获取商品列表
	GetProductList(ctx context.Context, params ProductQueryParams) ([]Product, int64, error)

	// GetProduct 根据ID获取商品详情
	GetProduct(ctx context.Context, productID string) (*Product, error)

	// CreateProduct 创建商品
	CreateProduct(ctx context.Context, product *Product) error

	// UpdateProduct 更新商品信息
	UpdateProduct(ctx context.Context, productID string, product *Product) error

	// DeleteProduct 删除商品
	DeleteProduct(ctx context.Context, productID string) error

	// GenerateUploadUrls 生成商品图片上传链接
	GenerateUploadUrl(ctx context.Context, filename string) (*wxcloud.UploadFileResponse, error)

	// UploadFiles 直接上传文件到云存储
	UploadFile(ctx context.Context, uploadResp *wxcloud.UploadFileResponse, filePath string, data []byte) error

	// GetProductsByType 根据类型获取商品列表
	GetProductsByType(ctx context.Context, productType ProductType) ([]Product, error)

	// GetProductsByStatus 根据状态获取商品列表
	GetProductsByStatus(ctx context.Context, status ProductStatus) ([]Product, error)

	// UpdateProductStatus 更新商品状态
	UpdateProductStatus(ctx context.Context, productID string, status ProductStatus) error

	// UpdateProductStock 更新商品库存
	UpdateProductStock(ctx context.Context, productID string, stock int) error

	// GetProductStats 获取商品统计信息
	GetProductStats(ctx context.Context) (*ProductStats, error)

	// SearchProducts 搜索商品
	SearchProducts(ctx context.Context, keyword string) ([]Product, error)
}

// UploadFile 上传文件结构体
type UploadFile struct {
	FileHeader  *multipart.FileHeader `json:"-"`           // 文件头信息
	FieldName   string                `json:"fieldName"`   // 表单字段名
	FileName    string                `json:"fileName"`    // 文件名
	Size        int64                 `json:"size"`        // 文件大小
	ContentType string                `json:"contentType"` // 文件MIME类型
	Data        []byte                `json:"-"`           // 文件数据
}

// UploadResult 上传结果结构体
type UploadResult struct {
	FieldName   string `json:"fieldName"`       // 表单字段名
	FileName    string `json:"fileName"`        // 原始文件名
	CloudPath   string `json:"cloudPath"`       // 云存储路径
	FileID      string `json:"fileId"`          // 云存储文件ID
	DownloadURL string `json:"downloadUrl"`     // 下载链接
	Size        int64  `json:"size"`            // 文件大小
	Success     bool   `json:"success"`         // 上传是否成功
	Error       string `json:"error,omitempty"` // 错误信息
}

// FileValidator 文件验证器
type FileValidator struct {
	maxSize      int64    // 最大文件大小（字节）
	allowedTypes []string // 允许的文件类型
	allowedExts  []string // 允许的文件扩展名
	maxCount     int      // 最大文件数量
}

// NewFileValidator 创建文件验证器
func NewFileValidator(maxSize int64, allowedTypes []string, allowedExts []string, maxCount int) *FileValidator {
	return &FileValidator{
		maxSize:      maxSize,
		allowedTypes: allowedTypes,
		allowedExts:  allowedExts,
		maxCount:     maxCount,
	}
}

// ValidateFiles 验证上传文件
func (fv *FileValidator) ValidateFiles(files []UploadFile) error {
	if len(files) == 0 {
		return errors.New(http.StatusBadRequest, "至少需要上传一个文件")
	}

	if len(files) > fv.maxCount {
		return errors.New(http.StatusBadRequest, fmt.Sprintf("最多只能上传 %d 个文件", fv.maxCount))
	}

	for _, file := range files {
		if err := fv.ValidateFile(file); err != nil {
			return err
		}
	}

	return nil
}

// ValidateFile 验证单个文件
func (fv *FileValidator) ValidateFile(file UploadFile) error {
	// 验证文件大小
	if file.Size > fv.maxSize {
		return errors.New(http.StatusBadRequest, fmt.Sprintf("文件 %s 大小超过限制 %d MB", file.FileName, fv.maxSize/(1024*1024)))
	}

	// 验证文件类型
	if len(fv.allowedTypes) > 0 {
		allowed := false
		for _, allowedType := range fv.allowedTypes {
			if file.ContentType == allowedType {
				allowed = true
				break
			}
		}
		if !allowed {
			return errors.New(http.StatusBadRequest, fmt.Sprintf("不支持的文件类型: %s", file.ContentType))
		}
	}

	// 验证文件扩展名
	if len(fv.allowedExts) > 0 {
		allowed := false
		ext := strings.ToLower(filepath.Ext(file.FileName))
		for _, allowedExt := range fv.allowedExts {
			if ext == strings.ToLower(allowedExt) {
				allowed = true
				break
			}
		}
		if !allowed {
			return errors.New(http.StatusBadRequest, fmt.Sprintf("不支持的文件扩展名: %s", ext))
		}
	}

	return nil
}

// 定义商品相关错误
var (
	ErrProductNotFound      = errors.New(http.StatusNotFound, "商品不存在")
	ErrProductNameRequired  = errors.New(http.StatusBadRequest, "商品名称不能为空")
	ErrProductPriceInvalid  = errors.New(http.StatusBadRequest, "商品价格不能为负数")
	ErrProductTypeRequired  = errors.New(http.StatusBadRequest, "商品类型不能为空")
	ErrProductStockInvalid  = errors.New(http.StatusBadRequest, "商品库存不能为负数")
	ErrProductAlreadyExists = errors.New(http.StatusConflict, "商品已存在")
)
